package com.fmboy.MXH.nav.interceptor;

import com.fmboy.MXH.nav.domain.AdminRequired;
import com.fmboy.MXH.nav.exception.UnauthorizedException;
import com.fmboy.MXH.nav.utils.JwtTool;
import com.fmboy.MXH.nav.utils.UserContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.io.PrintWriter;

@Component
@Slf4j
@RequiredArgsConstructor
public class JwtUserInterceptor implements HandlerInterceptor {

    private final JwtTool jwtTool;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod handlerMethod)) {
            return true; // 放行非Controller请求
        }

        // 检查方法上是否有 @AdminRequired 注解
        AdminRequired adminRequiredMethod = handlerMethod.getMethodAnnotation(AdminRequired.class);

        // 如果方法上没有注解，检查类上是否有 @AdminRequired 注解
        AdminRequired adminRequiredClass = handlerMethod.getBeanType().getAnnotation(AdminRequired.class);

        // 解析 JWT token，获取 userId
        String token = request.getHeader("Authorization");
        Long userId = null;
        try {
            userId = jwtTool.parseToken(token); // 获取 userId
        } catch (UnauthorizedException e) {
            log.warn("JWT 校验失败: {}", e.getMessage());
            sendErrorResponse(response, e.getMessage());
            return false; // 返回 false 以终止请求处理
        } catch (Exception e) {
            log.error("意外错误: {}", e.getMessage(), e);
            sendErrorResponse(response, "系统内部错误");
            return false; // 返回 false 以终止请求处理
        }

        // 将 userId 存入当前线程的 UserContext
        UserContext.setUserId(userId);

        // 获取用户角色
        String role = jwtTool.getRoleFromToken(request);

        // 如果方法或类要求 admin 权限，进行权限校验
        if ((adminRequiredMethod != null || adminRequiredClass != null) && !"admin".equals(role)) {
            log.warn("权限不足：用户不是 admin 角色");
            sendErrorResponse(response, "权限不足，只有管理员才能访问该接口");
            return false;
        }

        log.info("JWT 校验通过，用户ID: {}, 角色: {}", userId, role);
        return true; // 校验通过，继续请求处理
    }


    // 用于发送错误响应
    private void sendErrorResponse(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403 Forbidden
        response.setContentType("application/json; charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write("{\"status\": 403, \"error\": \"" + message + "\"}");
        out.flush();
    }
}
